package io.noties.markwon

import android.content.Context
import android.text.TextUtils
import android.util.AttributeSet
import androidx.annotation.ColorInt
import androidx.appcompat.widget.AppCompatTextView
import it.niedermann.android.markdown.MarkdownEditor
import io.noties.markwon.base.Markwon
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.LiveData
import java.util.concurrent.Executors
import java.util.function.Consumer
import java.util.function.Function

//@PrismBundle(includeAll = true, grammarLocatorClassName = ".MarkwonGrammarLocator")
abstract class MarkwonMarkdownViewer @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = android.R.attr.textViewStyle
) : AppCompatTextView(context, attrs, defStyleAttr), MarkdownEditor {
    protected lateinit var markwon: Markwon
    private var listener: Consumer<CharSequence>? = null
    private val unrenderedText = MutableLiveData<CharSequence>()
    private val renderService = Executors.newSingleThreadExecutor()

    /*protected Markwon _createMarkwon(@NonNull Context context) {
        return createMarkwonSampleBuilder(context).build();
    }

    protected  Markwon.Builder createMarkwonSampleBuilder(@NonNull Context context) {
        final Prism4jTheme prism4jTheme = MarkwonMarkdownUtil.isDarkThemeActive(context)
                ? Prism4jThemeDarkula.create()
                : Prism4jThemeDefault.create();
        return Markwon.builder(context)
                .usePlugin(ThemePlugin.create(context))
                .usePlugin(StrikethroughPlugin.create())
                .usePlugin(SimpleExtPlugin.create())
                .usePlugin(MarkwonInlineParserPlugin.create())
                .usePlugin(SearchHighlightPlugin.create(context))
                .usePlugin(TablePlugin.create(context))
                .usePlugin(TaskListPlugin.create(context))
                .usePlugin(LinkifyPlugin.create(true))
                .usePlugin(MovementMethodPlugin.create(TableAwareMovementMethod.create()))
                .usePlugin(LinkClickInterceptorPlugin.create())
                .usePlugin(GlideImagesPlugin.create(new CustomGlideStore(context)))
                .usePlugin(SoftBreakAddsNewLinePlugin.create())
                .usePlugin(SyntaxHighlightPlugin.create(prism4j, prism4jTheme))
                .usePlugin(new ToggleableTaskListPlugin((toggledCheckboxPosition, newCheckedState) -> {
                    final var oldUnrenderedText = unrenderedText$.getValue();
                    if (oldUnrenderedText == null) {
                        throw new IllegalStateException("Checkbox #" + toggledCheckboxPosition + ", but unrenderedText$ value is null.");
                    }
                    final var newUnrenderedText = MarkdownUtil.setCheckboxStatus(oldUnrenderedText.toString(), toggledCheckboxPosition, newCheckedState);
                    this.setMarkdownString(newUnrenderedText);
                }));
    }*/
    /*public Markwon.Builder createMarkwonBuilder(@NonNull Context context, @NonNull Map<String, String> mentions) {
        return createMarkwonSampleBuilder(context)
                .usePlugin(NextcloudMentionsPlugin.create(context, mentions));
    }*/
    override fun registerOnLinkClickCallback(callback: Function<String, Boolean>) {
        /*final var plugin = this.markwon.getPlugin(LinkClickInterceptorPlugin.class);
        if (plugin == null) {
            Log.w(TAG, "Tried to register callback, but " + LinkClickInterceptorPlugin.class.getSimpleName() + " is not a registered " + MarkwonPlugin.class.getSimpleName() + ".");
        } else {
            plugin.registerOnLinkClickCallback(callback);
        }*/
    }

    override fun setEnabled(enabled: Boolean) {
        /*final var plugin = this.markwon.getPlugin(ToggleableTaskListPlugin.class);
        if (plugin == null) {
            Log.w(TAG, "Tried to set enabled state for " + ToggleableTaskListPlugin.class.getSimpleName() + ", but " + ToggleableTaskListPlugin.class.getSimpleName() + " is not a registered " + MarkwonPlugin.class.getSimpleName() + ".");
        } else {
            plugin.setEnabled(enabled);
        }*/
    }

    override fun setMarkdownString(text: CharSequence) {
        setMarkdownString(text, null)
    }

    override fun setMarkdownString(text: CharSequence, afterRender: Runnable?) {
        val previousText = unrenderedText.value
        unrenderedText.value = text
        if (listener != null) {
            listener!!.accept(text)
        }
        if (TextUtils.isEmpty(text)) {
            setText(text)
        } else {
            if (text != previousText) {
                renderService.execute {
                    post {
                        markwon.setMarkdown(this, text.toString())
                        afterRender?.run()
                    }
                }
            }
        }
    }

    override fun setSearchColor(@ColorInt color: Int) {
        /*final var searchHighlightPlugin = this.markwon.getPlugin(SearchHighlightPlugin.class);
        if (searchHighlightPlugin == null) {
            Log.w(TAG, SearchHighlightPlugin.class.getSimpleName() + " is not a registered " + MarkwonPlugin.class.getSimpleName());
        } else {
            searchHighlightPlugin.setSearchColor(color, this);
        }*/
    }

    override fun setSearchText(searchText: CharSequence, current: Int?) {
        /* final var searchHighlightPlugin = this.markwon.getPlugin(SearchHighlightPlugin.class);
        if (searchHighlightPlugin == null) {
            Log.w(TAG, SearchHighlightPlugin.class.getSimpleName() + " is not a registered " + MarkwonPlugin.class.getSimpleName());
        } else {
            searchHighlightPlugin.setSearchText(searchText, current, this);
        }*/
    }

    override fun setMarkdownStringAndHighlightMentions(
        text: CharSequence,
        mentions: Map<String, String>
    ) {
        /* this.markwon = createMarkwonBuilder(getContext(), mentions).build();
        setMarkdownString(text);*/
    }

    override fun getMarkdownString(): LiveData<CharSequence> {
        return unrenderedText
    }

    override fun setMarkdownStringChangedListener(listener: Consumer<CharSequence>?) {
        this.listener = listener
    }

    companion object {

    }
}